<?php

namespace app\api\controller;

use app\api\library\Service;
use app\common\model\News as NewsModel;
use app\common\model\UserLike as UserLikeModel;
use app\common\model\UserFavorite as UserFavoriteModel;
use app\common\model\Channel;
use app\common\model\Comment;
use app\common\model\UserView;
use think\Exception;
use think\Db;
use think\Validate;
use fast\Tree;

/**
 * 文章
 */
class News extends Base
{
    protected $noNeedLogin = ['index', 'detail',"doLike","cancelLike","doFavorite","cancelFavorite","post","get_channel"];

    public function _initialize()
    {
        parent::_initialize();
        //检测ID是否加密
        $this->hashids();
    }
    /**
     * 获取栏目
     */
    public function get_channel()
    {
        $this->hashids('archives_id');
        $archives_id = $this->request->param('aid_id');
        $archives = $archives_id ? \NewsModel::get($archives_id) : null;
        $where = [];
        $channel_id = 0;
        $model = null;
        if ($archives) {
            $channel = Channel::get($archives['channel_id']);
            if (!$channel) {
                $this->error(__('未找到指定栏目'));
            }
   
            $channel_id = $archives['channel_id'];
        }
      
        list($channelList, $disabledIds) = Channel::getContributeInfo($archives, $model);
        foreach ($channelList as $index => &$item) {
            $item = array_intersect_key($item, array_flip(['id', 'parent_id', 'name', 'iscomment', 'model_id']));
        }
        unset($item);
        $tree = Tree::instance()->init($channelList, 'parent_id');
        $data = $tree->getTreeList($tree->getTreeArray(0, false));
        foreach ($data as &$item) {
            $item['disabled'] = in_array($item['id'], $disabledIds);
        }
        $this->success('', [
            'channel'    => $data,
//            'channel_id' => $channel_id
        ]);
    }
    /**
     * 读取文章列表
     */
    public function index()
    {
        $config = config();
        $params = [];
        $model = (int)$this->request->request('model');
        $channel = (int)$this->request->request('channel');
        $page = (int)$this->request->request('page');
        $params['type'] = (int)$this->request->request('type');
        $params['time'] = $this->request->request('time');
        $params['orderby'] = $this->request->request('orderby');
        $params['orderway'] = $this->request->request('orderway');
        if ($model) {
            $params['model'] = $model;
        }
        if ($channel) {
            $params['channel'] = $channel;
        }
        $page = max(1, $page);
        $params['limit'] = ($page - 1) * 10 . ',10';
        $params['cache'] = 0;
		
        if ($channel) {
            $channelInfo = Channel::get($channel);
            if ($channelInfo) {
                $channelIds = Channel::where(function ($query) use ($channelInfo) {
                    $channelInfo['listtype'] =1;
                    if ($channelInfo['listtype'] <= 2) {
                        $query->whereOr("id", $channelInfo['id']);
                    }
                    if ($channelInfo['listtype'] == 1 || $channelInfo['listtype'] == 3) {
                        $query->whereOr('id', 'in', function ($query) use ($channelInfo) {
                            $query->name("channels")->where('parent_id', $channelInfo['id'])->field("id");
                        });
                    }
                    if ($channelInfo['listtype'] == 0 || $channelInfo['listtype'] == 4) {
                        $childrenIds = \addons\cms\model\Channel::getChannelChildrenIds($channelInfo['id'], false);
                        if ($childrenIds) {
                            $query->whereOr('id', 'in', $childrenIds);
                        }
                    }
                })->column('id');
                $params['channel'] = $channelIds;
            }
        }
        $list = NewsModel::getArchivesList($params);
               
        $total = 0;
        if(isset($list['total'] )){
            $total = $list['total'];
            unset($list['total']);
        }
        $userNewsChecks = $this->mycheck($this->auth->id, 'news'); 
        $userCommentChecks = $this->mycheck($this->auth->id, 'comment'); 
        foreach($list as $key =>$value)
        {
            $list[$key]['is_mylike'] = 0;
            if(count($userNewsChecks['userLikes'])>1){
                foreach($userNewsChecks['userLikes'] as $likes){
                    if($value['id'] ==$likes['object_id']){
                        $list[$key]['is_mylike'] = 1;
                    }
                }
            }
            $list[$key]['is_myfavorite'] = 0;
            if(count($userNewsChecks['userFavorites'])>1){
                foreach($userNewsChecks['userFavorites'] as $fav){
                    if($value['id'] ==$fav['object_id']){
                        $list[$key]['is_myfavorite'] = 1;
                    }
                }
            }
            $commentList = Comment::getCommentList(['aid' => $value['id'],'type'=>'archives']);
            $commentList = $commentList->getCollection();
            foreach ($commentList as $index => &$item) {
                $item->is_mylike = 0;
                if(count($userCommentChecks['userLikes'])>1){
                    foreach($userCommentChecks['userLikes'] as $likes){
                        if($value['id'] ==$likes['object_id']){
                            $item->is_mylike = 1;
                        }
                    }
                }
//                $item->is_myfavorite = 0;
//                if(count($userCommentChecks['userFavorites'])>1){
//                    foreach($userCommentChecks['userFavorites'] as $likes){
//                        if($value['id'] ==$likes['object_id']){
//                            $item->is_myfavorite = 1;
//                        }
//                    }
//                }                
                if ($item->user) {
                    $item->user->avatar = cdnurl($item->user->avatar, true);
                    $item->user->visible(explode(',', 'id,nickname,avatar,bio'));
                }
                $item->hidden(['ip', 'useragent','status','delete_time', 'aid', 'subscribe', 'post_status', 'type', 'updatetime','deletetime']);
            }
            $list[$key]['commentList'] =$commentList;
        }
//        var_dump(Db::getLastsql());exit;
        
        $list = collection($list)->toArray();
        $this->success('', ['arList' => $list,'total'=>$total]);
    }
    public function mycheck($userId,$type= 'news')
    {   
        $userLikes = $userFavorites = [];
        if (!empty($userId) &&!empty($type)){
            //我的点赞
            $userLikeModel = new UserLikeModel();
            $userLikes = $userLikeModel->where([
                'user_id'   => $userId,
            ])->where('table_name', $type)->select();
            //我的收藏
            $userFavoriteModel = new UserFavoriteModel();
            $userFavorites = $userFavoriteModel->where([
                'user_id'   => $userId,
            ])->where('table_name', $type)->select();    
        }
    return ['userLikes' => $userLikes,'userFavorites' => $userFavorites];
    }
        /**
     * 日历标记（指定月份，有视频的日期标记出来）
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function calendarTag()
    {
        $param = $this->request->param();
        if (!isset($param['year_month']) || strlen($param['year_month']) != 7) {
            $this->error("日期参数错误！！");
        }
        $start = strtotime($param['year_month']);
        $end = strtotime(sprintf('%s +1month', $param['year_month']));
        $list = (new NewsModel())->field('id,create_time as time')->whereBetween('create_time', [$start, $end])->select();
        $temp = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'];
        $month = [];
        foreach ($temp as $item) {
            $month [sprintf('%s-%s', $param['year_month'], $item)] = 0;
        }
        foreach ($list as $row) {
            // 天数不要前面的0
            $day = date('Y-m-d', $row->time);
            isset($month[$day]) && $month[$day] += 1;
        }
        $this->success('', ['days' => $month, 'month' =>$param['year_month']]);
    }
    /**
     * 文章详情
     */
    public function detail()
    {
        $action = $this->request->post("action");
        if ($action && $this->request->isPost()) {
            return $this->$action();
        }
        $diyname = $this->request->param('diyname');
        $param = $this->request->param();
        if ($diyname && !is_numeric($diyname)) {
            $archives = NewsModel::getByDiyname($diyname);
        } else {
            $id = $param['id'];
            $archives = NewsModel::with('user')->where('id', $id)->find();
            $archives ->is_mylike = 0;
            $archives ->is_myfavorite = 0;
            $userId = $this->auth->id;
            $mylike = UserLikeModel::where([
            'user_id'   => $userId,
            'object_id' => $id
        ])->where('table_name', 'news')->count();
            if(!empty($mylike))$archives ->is_mylike = 1;
            $myFavorite = UserFavoriteModel::where([
                'user_id'   => $userId,
                'object_id' => $id
            ])->where('table_name', 'news')->count();
            $myFavorite = $myFavorite*1;
            if(!empty($myFavorite))$archives ->is_myfavorite = 1;
            $archives->user->visible(explode(',', 'id,nickname,avatar'));
            
        } 
        if (!$archives || ($archives['post_status'] != 1 && (!$archives['user_id'] || $archives['user_id'] != $this->auth->id)) || $archives['delete_time']) {
            $this->error(__('No specified article found'));
        }
//        if (!$this->auth->id && !$archives['post_hits']) {
//            $this->error(__('Please login first'));
//        }
        $channel = Channel::get($archives['parent_id']);
        if (!$channel) {
            $this->error(__('No specified channel found'));
        }
        $channel->hidden(['seo_title', 'seo_keywords', 'seo_description', 'list_order', 'delete_time','type','post_count','image','is_del']);
        $archives->setInc("post_hits", 1);
        if($this->auth->id){
            $data = [
                    'user_id'     => $this->auth->id,
                    'object_id'   => $id,
                    'table_name'  => 'news',
                    'title'       => $archives ->post_title,
                    'thumbnail'   => $archives ->thumbnail,
                    'description' => $archives ->post_excerpt,
                    'create_time' => time()
                    ];
            $userView = new UserView();
            $userView->addView($data);

        }
        //小程序付费阅读将不可见
        $content = $archives->content;


        //小程序不支持内容页分页
        $content = str_replace("##pagebreak##", "<br>", $content);
        $archives->content = $content;
        $archives->id = $archives->eid;
        $archives->hidden(['admin_id', 'delete_time', 'post_status', 'weigh', 'channel','is_del','post_content_filtered','update_time','published_time','post_format','post_type']);
        
        $commentList = Comment::getCommentList(['aid' => $archives['id']]);
        $commentList = $commentList->getCollection();
        $userCommentChecks = $this->mycheck($this->auth->id, 'comment'); 
        foreach ($commentList as $index => &$item) {
            $item->is_mylike = 0;
            if(count($userCommentChecks['userLikes'])>1){
                foreach($userCommentChecks['userLikes'] as $likes){
                    if($value['id'] ==$likes['object_id']){
                        $item->is_mylike = 1;
                    }
                }
            }
            if ($item->user) {
                $item->user->avatar = cdnurl($item->user->avatar, true);
                $item->user->visible(explode(',', 'id,nickname,avatar,bio'));
            }
            $item->hidden(['ip', 'useragent','status','delete_time', 'aid', 'subscribe', 'post_status', 'type', 'updatetime','deletetime']);
        }
        $this->request->token();
        $channel = $channel->toArray();
        unset( $channel['post_status'], $channel['weigh'], $channel['parent_id']);
        $this->success('', ['arInfo' => $archives, 'channelInfo' => $channel, 'commentList' => $commentList]);
    }

    /**
     * 提交数据
     */
    public function post()
    {
        // 如果来源于提交
        $config = config();
        $row = $this->request->post('', '', 'trim,xss_clean');
        $row = $this->request->get();
        $rule = [
            'post_title|标题'      => 'require|length:3,100',
            'channel_id|栏目' => 'require|integer',
            'thumbnail|缩略图' => 'require', 
            'post_content|内容' => 'require',
        ];

        $msg = [
            'post_title.require'   => '标题不能为空',
            'post_title.length'    => '标题长度限制在3~100个字符',
            'channel_id'      => '栏目不能为空',
            'thumbnail.require'       => '缩略图不能空',
            'post_content.require' => '内容不能为空',
        ];
        $validate = new Validate($rule, $msg);
        $result = $validate->check($row);
        if (!$result) {
            $this->error($validate->getError());
        }

        //如果有传栏目名称
        if (isset($row['channel']) && $row['channel']) {
            $channel = Channel::where('name', $row['channel'])->find();
            if (!$channel || $channel['status'] != 'normal') {
                $this->error('栏目未找到');
            }
            $row['channel_id'] = $channel->id;
            unset($row['channel']);
        } else {
            $channel_id = (isset($row['channel_id']) && !empty($row['channel_id'])) ? $row['channel_id'] : $this->request->request('channel_id');
            $channel = Channel::get($channel_id);
            if (!$channel || $channel['status'] != 1) {
                $this->error('栏目未找到');
            }
        }
  
        $channelIds = isset($row['channel_ids']) ? (is_array($row['channel_ids']) ? $row['channel_ids'] : explode(',', $row['channel_ids'])) : [];
        $channelIds = array_merge([$channel['id']], $channelIds);
        $channelIds = array_filter($channelIds);
        $count = Channel::where('id', 'in', $channelIds)->where('iscontribute', 0)->count();
        if ($count > 0) {
            $this->error("栏目不允许投稿");
        }

        //审核状态
        $status = 0;
        $row['parent_id'] = $row['channel_id'];
//        $row['user_id'] = $this->auth->id;
        $row['user_id'] = 2;
        $row['post_status'] = $status;
        $row['status'] = 0;
        $row['published_time'] = time();

        //编辑的时候
        $archives = null;
        if (isset($row['id']) && !empty((int)$row['id'])) {
            $archives = \app\admin\model\cms\News::get($row['id']);
            if ($archives['user_id'] != $this->auth->id) {
                $this->error("无法进行越权操作！");
            }
        } else {
            unset($row['id']);
        }
        Db::startTrans();
        try {
            if ($archives) {
                
                $archives->allowField(true)->save($row);
                $id = $row['id'];
            } else {
                (new \app\admin\model\cms\News)->allowField(true)->save($row);
                $id = Db::table("fa_news")->getLastInsID();
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error("发生错误:" . $e->getMessage());
        }
        if ($status === 'hidden') {
            //发送通知
            $status === 'hidden' && Service::notice(config('sitename') . '收到一篇新的文章审核');
            $this->success("提交成功！请等待审核!");
        } else {
            $this->success("发布成功！",['aid'=>$id]);
        }
    }
    /**
     * 我的发布
     */
    public function my()
    {
        $archives = new \app\common\model\News;
        $model = null;
        $model_id = (int)$this->request->request('model_id');
        $channel_id = (int)$this->request->request('channel_id');

        $config = ['query' => []];
        if ($model) {
            $config['query']['model_id'] = $model_id;
        }
        if ($channel_id) {
            $config['query']['channel_id'] = $channel_id;
        }
        $user_id = $this->auth->id;
//        $user_id = 2;
        $archivesList = $archives->where('user_id', $user_id)
            ->where($config['query'])
            ->field('id,user_id,post_title,parent_id as channel_id,post_like,post_favorites,post_forward,create_time,comment_count,post_hits,status')
            ->order('id', 'desc')
            ->paginate(10, null, $config);

        $channelList = Channel::where('id', 'in', function ($query) use ($user_id) {
            $query->name('news')->where('user_id', $user_id)->field('parent_id');
        })->where('status', 1)->select();
        foreach ($channelList as $index => &$item) {
            $item->visible(explode(',', 'id,parent_id,name,image,items'));
        }
        unset($item);

        foreach ($archivesList as $index => $item) {
            if ($item->channel) {
                $item->channel->visible(explode(',', 'id,parent_id,name,image'));
            }
            unset($item['weigh'], $item['delete_time']);
            $item->id = $item->eid;
        }

        $this->success('', [
            'archivesList' => $archivesList,
            'channelList'  => $channelList
        ]);
    }
    //点赞
     public function doLike()
    {
        $userId    = $this->auth->id;
//        $userId = 2;
        $articleId = $this->request->param('id', 0, 'intval');

        $userLikeModel = new UserLikeModel();

        $findLikeCount = $userLikeModel->where([
            'user_id'   => $userId,
            'object_id' => $articleId
        ])->where('table_name', 'news')->count();

        if (empty($findLikeCount)) {
            $postModel = new NewsModel();
            $article   = $postModel->where('id', $articleId)->field('id,post_title,post_excerpt')->find();

            if (empty($article)) {
                $this->error('文章不存在！');
            }

            Db::startTrans();
            try {
                    $postModel->where('id', $articleId)->setInc('post_like');
                

                $thumbnail = empty(['thumbnail']) ? '' : ['thumbnail'];
                $userLikeModel->insert([
                    'user_id'     => $userId,
                    'object_id'   => $articleId,
                    'table_name'  => 'news',
                    'title'       => $article['post_title'],
                    'thumbnail'   => $thumbnail,
                    'description' => $article['post_excerpt'],
//                    'url'         => json_encode(['action' => 'portal/Article/index', 'param' => ['id' => $articleId, 'cid' => $article['categories'][0]['id']]]),
                    'create_time' => time()
                ]);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error('点赞失败！');
            }

            $likeCount = $postModel->where('id', $articleId)->value('post_like');
            $this->success("赞好啦！", ['post_like' => $likeCount]);
        } else {
            $this->error("您已赞过啦！");
        }
    }

    /**
     * 取消文章点赞
     */
    public function cancelLike()
    {
        $userId = $this->auth->id;
//        $userId = 2;
        $articleId = $this->request->param('id', 0, 'intval');

        $userLikeModel = new UserLikeModel();

        $findLikeCount = $userLikeModel->where([
            'user_id'   => $userId,
            'object_id' => $articleId
        ])->where('table_name', 'news')->count();

        if (!empty($findLikeCount)) {
            $postModel = new NewsModel();
            Db::startTrans();
            try {
                $postModel->where('id' , $articleId)->setDec('post_like');
                $userLikeModel->where([
                    'user_id'   => $userId,
                    'object_id' => $articleId
                ])->where('table_name', 'news')->delete();
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error('取消点赞失败！');
            }

            $likeCount = $postModel->where('id', $articleId)->value('post_like');
            $this->success("取消点赞成功！", ['post_like' => $likeCount]);
        } else {
            $this->error("您还没赞过！");
        }
    }

    //转发
     public function doForward()
    {
        $userId    = $this->auth->id;
//        $userId = 2;
        $articleId = $this->request->param('id', 0, 'intval');

        $UserForwardModel = new UserForward();

        $findLikeCount = $UserForwardModel->where([
            'user_id'   => $userId,
            'object_id' => $articleId
        ])->where('table_name', 'news')->count();

        if (empty($findLikeCount)) {
            $postModel = new NewsModel();
            $article   = $postModel->where('id', $articleId)->field('id,post_title,post_excerpt')->find();

            if (empty($article)) {
                $this->error('文章不存在！');
            }

            Db::startTrans();
            try {
                $postModel->where('id', $articleId)->setInc('post_forward');
                $thumbnail = empty(['thumbnail']) ? '' : ['thumbnail'];
                $userLikeModel->insert([
                    'user_id'     => $userId,
                    'object_id'   => $articleId,
                    'table_name'  => 'news',
                    'title'       => $article['post_title'],
                    'thumbnail'   => $thumbnail,
                    'description' => $article['post_excerpt'],
                    'create_time' => time()
                ]);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error('转发失败！');
            }

            $likeCount = $postModel->where('id', $articleId)->value('post_forward');
            $this->success("转发！", ['post_forward' => $likeCount]);
        } else {
            $this->error("您已转发啦！");
        }
    }

   
    //收藏
    public function doFavorite()
    {
        $userId = $this->auth->id;
//       $userId = 2;
        $articleId = $this->request->param('id', 0, 'intval');

        $userFavoriteModel = new UserFavoriteModel();

        $findFavoriteCount = $userFavoriteModel->where([
            'user_id'   => $userId,
            'object_id' => $articleId
        ])->where('table_name', 'news')->count();

        if (empty($findFavoriteCount)) {
            $postModel = new NewsModel();
            $article   = $postModel ->where(['id' => $articleId])->field('id,post_title,post_excerpt')->find();
//            var_dump($article);exit;
            if (empty($article)) {
                $this->error('文章不存在！');
            }

            Db::startTrans();
            try {
                $postModel->where('id', $articleId)->setInc('post_favorites');  
                $thumbnail = empty($article['thumbnail']) ? '' : $article['thumbnail'];
                $userFavoriteModel->insert([
                    'user_id'     => $userId,
                    'object_id'   => $articleId,
                    'table_name'  => 'news',
                    'thumbnail'   => $thumbnail,
                    'title'       => $article['post_title'],
                    'description' => $article['post_excerpt'],
//                    'url'         => json_encode(['action' => 'portal/Article/index', 'param' => ['id' => $articleId, 'cid' => $article['categories'][0]['id']]]),
                    'create_time' => time()
                ]);
                
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();

                $this->error('收藏失败！');
            }

            $favoriteCount = $postModel->where('id', $articleId)->value('post_favorites');
            $this->success("收藏好啦！", ['post_favorites' => $favoriteCount]);
        } else {
            $this->error("您已收藏过啦！");
        }
    }

    /**
     * 取消文章收藏
    **/
    public function cancelFavorite()
    {
        $userId = $this->auth->id;
//        $userId = 2;
        $articleId = $this->request->param('id', 0, 'intval');

        $userFavoriteModel = new UserFavoriteModel();

        $findFavoriteCount = $userFavoriteModel->where([
            'user_id'   => $userId,
            'object_id' => $articleId
        ])->where('table_name', 'news')->count();

        if (!empty($findFavoriteCount)) {
            $postModel = new NewsModel();
            Db::startTrans();
            try {
                $postModel->where('id' , $articleId)->setDec('post_favorites');
                $userFavoriteModel->where([
                    'user_id'   => $userId,
                    'object_id' => $articleId
                ])->where('table_name', 'news')->delete();
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error('取消失败！');
            }

            $favoriteCount = $postModel->where('id', $articleId)->value('post_favorites');
            $this->success("取消成功！", ['post_favorites' => $favoriteCount]);
        } else {
            $this->error("您还没收藏过！");
        }
    }
    //用户文章列表
        public function user()
    {
        $userId = $this->request->param('id', 0, 'intval');

        if (empty($userId)) {
            $this->error('用户id不能空！');
        }

        $param             = $this->request->param();
        $param['user_id']  = $userId;
        $articles          = $archives->postArticles($param);
        if ($articles->isEmpty()) {
            $this->error('没有数据');
        } else {
            $this->success('ok', ['list' => $articles]);
        }
    }
     /**
     * 删除文档
     */
    public function delete()
    {
        if (!$this->request->isPost()) {
            $this->error('请求错误');
        }
        $id = (int)$this->request->post('id/d');
        if (!$id) {
            $this->error("参数不正确");
        }
        $archives = \app\common\model\News::where('id', $id)->where('user_id', $this->auth->id)->find();
        if (!$archives) {
            $this->error("未找到指定的文档");
        }
        Db::startTrans();
        try {
            $archives->delete();
            if ($archives->channel->items > 0) {
                $archives->channel->setDec("items");
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            $this->error("删除文档失败");
        }
        $this->success("删除文档成功");
    }
}
